package weifei.wx.community.service;


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import lombok.Getter;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;


@EnableScheduling
@Service
public class WXService
{
    public static final String TOKEN_PASSWORD_AFTER = "password";
    public static final String APP_ID = "wxa862dc2af65b7568";
    public static final String APP_SECRET = "a8eba24677bc3492a500ec5d176209b6";

    private static final HashMap<Long, String> USER_ID_ACCESS_TOKEN_MAP = new HashMap<>();
    private static final HashMap<String, Long> USER_ACCESS_TOKEN_ID_MAP = new HashMap<>();


    private final RestTemplate restTemplate = new RestTemplate();
    @Getter
    private String accessToken = null;  // 调用微信API的token



    public WXService()
    {
        // this.refreshAccessToken();
    }



    public String get(String url)
    {
        return this.restTemplate.getForObject(url, String.class);
    }

    public String post(String url, Object request)
    {
        return this.restTemplate.postForObject(url, request, String.class);
    }


    @Scheduled(cron="0 0 0/1 * * ? ")
    private void refreshAccessToken()
    {
        this.accessToken = this.get(
                "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" +
                WXService.APP_ID +
                "&secret=" +
                WXService.APP_SECRET
        );
        System.out.print("refresh access_token: ");
        System.out.println(this.accessToken);
    }


    public static void saveUserAccessToken(Long uid, String token)
    {
        String oldToken = WXService.USER_ID_ACCESS_TOKEN_MAP.get(uid);
        if (oldToken != null)
            WXService.USER_ACCESS_TOKEN_ID_MAP.remove(oldToken);
        WXService.USER_ID_ACCESS_TOKEN_MAP.put(uid, token);
        WXService.USER_ACCESS_TOKEN_ID_MAP.put(token, uid);
    }


    public static boolean verifyUserAccessToken(String token)
    {
        Long uid = WXService.USER_ACCESS_TOKEN_ID_MAP.get(token);
        if (uid == null)
            return false;

        String sessionKey = JWT.decode(token).getClaim("session_key").asString();
        if (sessionKey == null || sessionKey.isEmpty())
            return false;

        try {
            JWTVerifier jwtVerifier = JWT
                .require(Algorithm.HMAC256(sessionKey + WXService.TOKEN_PASSWORD_AFTER))
                .build();
            jwtVerifier.verify(token);
        } catch (JWTVerificationException e) {
            WXService.USER_ID_ACCESS_TOKEN_MAP.remove(uid);
            WXService.USER_ACCESS_TOKEN_ID_MAP.remove(token);
            return false;
        }
        return true;
    }
}


